package com.ctshk.rpc.order.scenic.service.impl.app;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.constant.RedisConstants;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.Currency;
import com.ctshk.common.enums.*;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.*;
import com.ctshk.rpc.booking.enums.SupplierReserveTypeEnum;
import com.ctshk.rpc.booking.req.system.admission.add.SupplierOrderSystemAdmissionAddReq;
import com.ctshk.rpc.booking.req.system.admission.add.SupplierSystemOrderAdmissionTicketAddReq;
import com.ctshk.rpc.booking.req.system.admission.add.SupplierSystemOrderAdmissionTicketDetailAddReq;
import com.ctshk.rpc.booking.service.ISupplierOrderService;
import com.ctshk.rpc.finance.req.bill.BillAddCollectionReq;
import com.ctshk.rpc.finance.req.bill.BillAddRefundReq;
import com.ctshk.rpc.finance.service.IFinanceBillService;
import com.ctshk.rpc.order.scenic.dto.*;
import com.ctshk.rpc.order.scenic.dto.app.AppScenicDTO;
import com.ctshk.rpc.order.scenic.dto.app.AppScenicOrderDTO;
import com.ctshk.rpc.order.scenic.entity.*;
import com.ctshk.rpc.order.scenic.mapper.*;
import com.ctshk.rpc.order.scenic.mapper.app.AppScenicOrderMapper;
import com.ctshk.rpc.order.scenic.req.ScenicProductOrderReq;
import com.ctshk.rpc.order.scenic.req.*;
import com.ctshk.rpc.order.scenic.service.app.IAppScenicOrderService;
import com.ctshk.rpc.scenic.dto.ScenicProductCostStrategySpecAttrDTO;
import com.ctshk.rpc.scenic.dto.*;
import com.ctshk.rpc.scenic.req.ScenicProductTicketListReq;
import com.ctshk.rpc.scenic.req.*;
import com.ctshk.rpc.scenic.service.IScenicProductCostStrategySpecAttrService;
import com.ctshk.rpc.scenic.service.IScenicProductService;
import com.ctshk.rpc.scenic.service.IScenicResourceTicketService;
import com.ctshk.rpc.system.dto.*;
import com.ctshk.rpc.system.req.MainDataCurrencyListReq;
import com.ctshk.rpc.system.req.MainDataCurrencyUpdateStatusReq;
import com.ctshk.rpc.system.service.*;
import com.ctshk.rpc.workflow.dto.ApprovalCheckDTO;
import com.ctshk.rpc.workflow.dto.ApprovalStartDTO;
import com.ctshk.rpc.workflow.service.ISysApprovalService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 景点门票订单 服务实现类
 * </p>
 *
 * @author 黄先
 * @since 2021-6-2
 */
@SuppressWarnings("all")
@Slf4j
@DubboService
public class AppScenicOrderServiceImpl extends ServiceImpl<ScenicOrderMapper, ScenicOrder> implements IAppScenicOrderService {
    @Autowired
    AppScenicOrderMapper appScenicOrderMapper;

    @Autowired
    RedisTemplate<String, String> redisTemplate;

    @Autowired
    private ScenicOrderMapper scenicOrderMapper;

    @Autowired
    private ScenicOrderTouristMapper scenicOrderTouristMapper;

    @Autowired
    private ScenicManualOrderMapper scenicManualOrderMapper;

    @Autowired
    private ScenicOrderCollectionMapper scenicOrderCollectionMapper;

    @Autowired
    private ScenicOrderRefundMapper scenicOrderRefundMapper;

    @DubboReference
    private IScenicProductService iScenicProductService;

    @DubboReference
    private IMainDataCurrencyService iMainDataCurrencyService;

    @DubboReference
    private ISysPermissionService sysPermissionService;

    @DubboReference
    private IScenicProductCostStrategySpecAttrService scenicProductCostStrategySpecAttrService;

    @DubboReference
    private ISysApprovalService iSysApprovalService;

    @Autowired
    private ScenicOrderReceiptMapper scenicOrderReceiptMapper;

    @DubboReference
    private ISysUserService iSysUserService;

    @DubboReference
    private ISupplierOrderService iSupplierOrderService;

    @DubboReference
    private ISysDepartmentService sysDepartmentService;

    @DubboReference
    private IScenicResourceTicketService scenicResourceTicketService;

    @DubboReference
    private IFinanceBillService financeBillService;

    @DubboReference
    private IScenicProductService scenicProductService;

    @DubboReference
    private ISceneService sceneService;

    @DubboReference
    private IScenicResourceTicketService iScenicResourceTicketService;

    @DubboReference
    ISysUserService sysUserService;

    @Override
    public Result<AppScenicOrderDTO> findScenicOrderInfoByNumber(String number) {
        Object o = redisTemplate.opsForValue().get(RedisConstants.SCENIC_ORDER_DETAILS + number);
        AppScenicOrderDTO appScenicOrderDTO = null;
        if(o == null){
            appScenicOrderDTO = appScenicOrderMapper.findScenicOrderInfoByNumber(number);
            if(appScenicOrderDTO != null){
                String productTicketsId = appScenicOrderDTO.getProductTicketsId();
                if(productTicketsId != null){
                    List<AppScenicDTO> appScenicDTOS = appScenicOrderMapper.selectScenicNameByScenicIds(productTicketsId);
                    appScenicOrderDTO.setAppScenicDTOList(appScenicDTOS);
                }
            }
            // 将数据库查询出的结果放到缓存中 15-25分钟失效
            int lastTime = 15 + new Random().nextInt(10);
            redisTemplate.opsForValue().set(RedisConstants.SCENIC_ORDER_DETAILS + appScenicOrderDTO.getOrderNumber(), JSON.toJSONString(appScenicOrderDTO), lastTime, TimeUnit.MINUTES);
            redisTemplate.opsForValue().set(RedisConstants.SCENIC_ORDER_DETAILS + appScenicOrderDTO.getQueryNumber(), JSON.toJSONString(appScenicOrderDTO), lastTime, TimeUnit.MINUTES);
        }else{
            appScenicOrderDTO = JSON.parseObject((String)o, AppScenicOrderDTO.class);
        }
        return Result.success(appScenicOrderDTO);
    }

    @Override
    public List<AppScenicDTO> selectScenicNameByScenicIds(String scenicIds) {
        return appScenicOrderMapper.selectScenicNameByScenicIds(scenicIds);
    }


    /**
     * 填写订单页新增订单与游客信息
     *
     * @param scenicAddCheckOrderReq 填写订单页新增订单与游客信息入参
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result addOrderInfo(ScenicAddCheckOrderReq scenicAddCheckOrderReq, Long userId) {
        UserDTO userDTO = null;
        SysDepartmentDTO departmentDTO = null;
        try {
            userDTO = iSysUserService.loadUserByParam(userId, 1);
            if (userDTO != null) {
                departmentDTO = sysDepartmentService.queryOne(userDTO.getDeptId());
            }
        } catch (Exception e) {
//            throw new BusinessException(SystemError.SYS_502);
        }
        ScenicOrderInputCheckReq inputCheckReq = scenicAddCheckOrderReq.getScenicOrderInputCheckReq();
        List<ScenicOrderTouristInputCheckReq> touristInfos = scenicAddCheckOrderReq.getTouristInfos();
        ScenicOrder scenicOrder = EntityUtil.copy(inputCheckReq, ScenicOrder.class);
        ScenicProductListDTO dto = iScenicProductService.queryById(scenicOrder.getProductId()).getData();
        Result<List<ScenicResourceTicketDTO>> ticketDTOList =
                scenicResourceTicketService.queryByStockId(inputCheckReq.getStockId(),touristInfos.size());
        //查詢出成本價以及匯率  供应商的总价格是成本价*汇率
        ScenicChargeDTO chargeDTO=  scenicResourceTicketService.queryChargeByStockId(inputCheckReq.getStockId()).getData();
        if(CollectionUtil.isEmpty(ticketDTOList.getData())||ticketDTOList.getData().size()!=touristInfos.size()){
           return null; //库存不足
        }
        // 订单id
        long orderId = SnowflakeIdWorker.nextId();
        scenicOrder.setId(orderId);
        scenicOrder.setProductType(ProductType.MANUAL_ENTRY.getCode());
        scenicOrder.setUserId(userId);
        scenicOrder.setSalesmanId(userId);
        scenicOrder.setSalesmanName(userDTO.getCnName());
        scenicOrder.setSource(dto.getSourceType());
        // 服务个数&单张服务费
        Integer num = inputCheckReq.getServiceNum();
        BigDecimal fee = inputCheckReq.getFee();
        // 总服务费
        BigDecimal decimal = BigDecimal.ZERO;
        if (null != num && null != fee) {
            decimal = fee.multiply(BigDecimal.valueOf(num));
            scenicOrder.setServiceFee(decimal);
        }
        // 门票总数量&单张门票价格
        Integer ticketNum = inputCheckReq.getNum();
        BigDecimal singleTicketFee = inputCheckReq.getSingleTicketFee();
        BigDecimal multiply = singleTicketFee.multiply(BigDecimal.valueOf(ticketNum));
        //供应商的总价格是成本价*汇率

        scenicOrder.setSingleTicketFee(singleTicketFee);
        //生成查询单号
        String queryNumber = String.valueOf((int) (Math.random() * (999999 - 100000 + 1)) + 100000);
        scenicOrder.setQueryNumber(queryNumber);
        // 积分费用
        BigDecimal integralFee = inputCheckReq.getIntegralDeduction();
        // 推广码优惠券费用
        BigDecimal couponDeduction = inputCheckReq.getCouponDeduction();

        // 门票总价格(加上服务费)
        BigDecimal ticketFee = decimal.add(multiply);
        scenicOrder.setTicketsFee(ticketFee);

        // 订单总额
        integralFee = Objects.isNull(integralFee) ? BigDecimal.ZERO : integralFee;
        couponDeduction = Objects.isNull(couponDeduction) ? BigDecimal.ZERO : couponDeduction;
        BigDecimal orderFee = ticketFee.subtract(integralFee).subtract(couponDeduction);
        scenicOrder.setOrderAmount(orderFee);
        scenicOrder.setReceivableAmount(orderFee);
        scenicOrder.setCreateId(userId);
        LocalDateTime now = LocalDateTime.now();
        scenicOrder.setGmtCreate(now);
        scenicOrder.setGmtModified(now);
        //付款状态 1  待付款  2 已付款  3 订单取消
        scenicOrder.setPaymentStatus(1);
        //门票数量
        scenicOrder.setProductTicketNumber(ticketNum);
        // 计算付款到期时间,+30分钟
        scenicOrder.setPayExpireDate(LocalDateTime.now().plusMinutes(30));
        //生成销售单号  M++年後2位+月日4位+3位隨機數字
        String orderNumber = null;
        if (departmentDTO != null && userDTO != null) {
            orderNumber = "M" + departmentDTO.getDeptCode() + userDTO.getEmployeeNumber() + DateUtil.fmtLocalDate(LocalDate.now(), "yyMMdd") + CharUtil.getRandomStr(3);
            scenicOrder.setOrderNumber(orderNumber);
        }
        for(ScenicResourceTicketDTO ticketDTO:ticketDTOList.getData()){
            ScenicResourceTicketUpdateReq req = new ScenicResourceTicketUpdateReq();
            req.setId(ticketDTO.getId());
            req.setSaleNumber(orderNumber);
            req.setSalerId(userId);
            req.setSalerName(userDTO.getCnName());
            req.setDepartmentId(departmentDTO.getId());
            req.setDepartmentName(departmentDTO.getTitle());
            scenicResourceTicketService.update(req);
        }
        List<Long> productids=ticketDTOList.getData().stream().map(ScenicResourceTicketDTO::getId).collect(Collectors.toList());
        scenicOrder.setProductTicketsId(StringUtils.join(productids,","));
        scenicOrder.setUserId(userId);
        scenicOrderMapper.insert(scenicOrder);
        List<SupplierSystemOrderAdmissionTicketAddReq> mpxinxi=new ArrayList<>();
        SupplierSystemOrderAdmissionTicketAddReq sp=new SupplierSystemOrderAdmissionTicketAddReq();
        List<SupplierSystemOrderAdmissionTicketDetailAddReq> mpxxaignqin
                = new ArrayList<>();
        List<ProductTicketDTO> productTicketDTOS=new ArrayList<>();
        sp.setOrderId(orderId);
        sp.setSuitablePeople(dto.getIntendedUser());
        sp.setCustomerRemark(inputCheckReq.getRemark());
        if (CollectionUtils.isNotEmpty(touristInfos)) {
            ScenicOrderTourist scenicOrderTourist;
            for(int i=0;i<touristInfos.size();i++){
                ScenicOrderTouristInputCheckReq touristInfo=touristInfos.get(i);
                scenicOrderTourist = EntityUtil.copy(touristInfo, ScenicOrderTourist.class);
                scenicOrderTourist.setId(SnowflakeIdWorker.nextId());
                scenicOrderTourist.setOrderId(orderId);
                scenicOrderTourist.setTicketsProductId(ticketDTOList.getData().get(i).getId());
                scenicOrderTourist.setCreateId(userId);
                scenicOrderTouristMapper.insert(scenicOrderTourist);
                ProductTicketDTO ticketDTO=new ProductTicketDTO();
                ticketDTO.setProductTickeId(ticketDTOList.getData().get(i).getId());
                ticketDTO.setStocketNumber(ticketDTOList.getData().get(i).getStockNumber());
                HashMap map = new HashMap();
                SupplierSystemOrderAdmissionTicketDetailAddReq detailAddReq
                        = new SupplierSystemOrderAdmissionTicketDetailAddReq();
                detailAddReq.setOrderId(scenicOrder.getId());
                detailAddReq.setTicketTypeName(dto.getName() == null ? "" : dto.getName());
                detailAddReq.setNumber(1);
                detailAddReq.setUnitPrice(inputCheckReq.getSingleTicketFee());
                map.put("touristType", touristInfo.getTouristType());
                map.put("touristTitle", touristInfo.getAppellation());
                map.put("touristName", touristInfo.getTouristName());
                String resultJson = JSON.toJSONString(map);
                detailAddReq.setPassengerJson(resultJson);
                mpxxaignqin.add(detailAddReq);//传给供应商模块的预订信息
                productTicketDTOS.add(ticketDTO); //把票号跟id传给供应商模块
            }
        }
        sp.setTicketNumber(JSON.toJSONString(productTicketDTOS));
        sp.setSupplierSystemOrderAdmissionTicketDetailAddReqList(mpxxaignqin);
        mpxinxi.add(sp);
        scenicProductCostStrategySpecAttrService.updateStock(inputCheckReq.getStockId(),ticketNum);
        SupplierOrderSystemAdmissionAddReq req = new SupplierOrderSystemAdmissionAddReq();
        req.setSupplierSystemOrderAdmissionAddReqList(mpxinxi);
        req.setSupplierId(dto.getSupplierId());
        req.setSupplierName(dto.getSupplierName());
            //供应商订单类型(1:普通订单,2:内部挂账订单)
        req.setSupplierOrderType("1");
        req.setProductNumber(dto.getProductCode());
        req.setProductName(dto.getName());
        req.setReserveTypeId(SupplierReserveTypeEnum.SCENIC.getId());
        req.setTotalFee(chargeDTO.getCostPrice().multiply(BigDecimal.valueOf(chargeDTO.getExchangeRate())).
                multiply(BigDecimal.valueOf(ticketNum)));
        //需要二次确认的  修改状态
        if(Objects.isNull(dto.getBookConfirm())||dto.getBookConfirm()==1){
            req.setReserveStatus(OrderScheduledStatus.RESERVE_SUCCESS.getCode());
        }else{
            req.setReserveStatus(OrderScheduledStatus.CONFIRM_RESERVE.getCode());
        }
        req.setOriginalSaleNumber("");
        //业务类型
        req.setBusinessType(SystemBusinessType.ATTRACTION_TICKET.getCode());
        //单品销售
        req.setSaleType(SalesMethod.SINGLE_SALE.getCode());
        req.setReserveTypeId(SupplierReserveTypeEnum.SCENIC.getId());
        req.setProductType(ProductType.MANUAL_ENTRY.getCode());
        if (userDTO != null) {
            req.setDepartmentId(userDTO.getDeptId());
            req.setDepartment(userDTO.getDept());
        } else {
            req.setDepartmentId(0l);
            req.setDepartment("");
        }
        req.setSaleNumber(scenicOrder.getOrderNumber());
        req.setCurrencyId(Currency.HKD.getCode());
        req.setCurrency(Currency.HKD.getCurrency());
        req.setPayableAmount(scenicOrder.getReceivableAmount());
        req.setRemark(scenicOrder.getRemark());
        //生成供应商预订单
        iSupplierOrderService.addSystemAdmission(req, userId);
        return Result.success(orderId);
    }

    /**
     * 新增外挂单
     *
     * @param scenicManualOrderReq 新增外挂单入参
     * @param id                   用户id
     * @return 返回值
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Long> addManualOrder(ScenicManualOrderReq scenicManualOrderReq, Long id,TokenUser tokenUser) {
        try {
            ScenicManualOrder manualOrder = EntityUtil.copy(scenicManualOrderReq, ScenicManualOrder.class);
            manualOrder.setId(SnowflakeIdWorker.nextId());
            long orderId = SnowflakeIdWorker.nextId();
            manualOrder.setOrderId(orderId);
            int insertManualOrder = scenicManualOrderMapper.insert(manualOrder);
            if (insertManualOrder < 1) {
                throw new BusinessException(SystemError.SYS_437);
            }
            UserDTO userDTO = null;
            SysDepartmentDTO departmentDTO = null;
            try {
                userDTO = iSysUserService.loadUserByParam(tokenUser.getId(), 1);
                if (userDTO != null) {
                    departmentDTO = sysDepartmentService.queryOne(userDTO.getDeptId());
                }
            } catch (Exception e) {
                throw new BusinessException(SystemError.SYS_502);
            }
            ScenicOrder scenicOrder = EntityUtil.copy(scenicManualOrderReq, ScenicOrder.class);
            scenicOrder.setId(orderId);
            scenicOrder.setUserId(id);
            scenicOrder.setCreateId(id);
            scenicOrder.setProductType(ProductType.PLUG.getCode());
            scenicOrder.setPaymentStatus(1);
            // 服务个数&单张服务费
            Integer num = scenicManualOrderReq.getNumber();
            BigDecimal fee = scenicManualOrderReq.getServiceAmount();
            // 总服务费
            BigDecimal decimal = BigDecimal.ZERO;
            if (null != num && null != fee) {
                decimal = fee.multiply(BigDecimal.valueOf(num));
                scenicOrder.setServiceFee(decimal);
            }
            // 门票总数量&单张门票价格
            scenicOrder.setTicketsFee(scenicManualOrderReq.getExpendAmount());
            scenicOrder.setOrderAmount(scenicManualOrderReq.getExpendAmount());
            //生成查询单号
            String queryNumber = String.valueOf((int) (Math.random() * (999999 - 100000 + 1)) + 100000);
            scenicOrder.setQueryNumber(queryNumber);
            // 计算付款到期时间,+30分钟
            scenicOrder.setPayExpireDate(LocalDateTime.now().plusMinutes(30));
            //生成销售单号  M++年後2位+月日4位+3位隨機數字
            if (departmentDTO != null && userDTO != null) {
                String orderNumber = "M" + departmentDTO.getDeptCode() + userDTO.getEmployeeNumber() + DateUtil.fmtLocalDate(LocalDate.now(), "yyMMdd") + CharUtil.getRandomStr(3);
                scenicOrder.setOrderNumber(orderNumber);
            }
            int insertOrder = scenicOrderMapper.insert(scenicOrder);
            if (insertOrder < 1) {
                throw new BusinessException(SystemError.SYS_437);
            }
            return Result.success(orderId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.failed(SystemError.SYS_437);
    }

    /**
     * 积分兑换港币 ￥
     *
     * @param integral 积分
     * @return 返回值
     */
    @Override
    public Result<ScenicOrderIntegralExchangeDTO> conversionIntegral(Long integral) {
        ScenicOrderIntegralExchangeDTO scenicOrderIntegralExchangeDTO = new ScenicOrderIntegralExchangeDTO();

        MainDataCurrencyListReq mainDataCurrencyListReq = new MainDataCurrencyListReq();
        mainDataCurrencyListReq.setName("CNY");
        PageResponse<MainDataCurrencyListDTO> list = iMainDataCurrencyService.list(mainDataCurrencyListReq);
        List<MainDataCurrencyListDTO> records = list.getRecords();
        if (CollectionUtils.isNotEmpty(records)) {
            // 人民币id
            Long id = records.get(0).getId();
            MainDataCurrencyUpdateStatusReq currencyUpdateStatusReq = new MainDataCurrencyUpdateStatusReq();
            currencyUpdateStatusReq.setId(id);
            Result<MainDataCurrencyQueryDTO> queryDTOResult = iMainDataCurrencyService.query(currencyUpdateStatusReq);
            MainDataCurrencyQueryDTO result = queryDTOResult.getData();
            if (null != result) {
                // 人民币兑换港币汇率
                BigDecimal crmExchangeRate = result.getCrmExchangeRate();

                // 积分
                Integer integralNum = Integer.valueOf(integral.toString());

                // 积分兑换人民币
                Integer var = integralNum / 100;

                BigDecimal money = crmExchangeRate.multiply(BigDecimal.valueOf(var));

                scenicOrderIntegralExchangeDTO.setIntegral(integral);
                scenicOrderIntegralExchangeDTO.setIntegralDeduction(money);
                return Result.success(scenicOrderIntegralExchangeDTO);
            }
        }
        return null;
    }

    /**
     * 根据订单id查询订单信息
     *
     * @param orderId 订单id
     * @return 订单信息
     */
    @Override
    public Result<ScenicOrderPayQueryInfoDTO> queryOrderInfo(Long orderId) {
        try {
            ScenicOrder scenicOrder = scenicOrderMapper.selectById(orderId);
            if (null == scenicOrder) {
                throw new BusinessException(SystemError.SYS_411);
            }
            // 应收总额
            BigDecimal orderAmount = scenicOrder.getOrderAmount();
            LocalDateTime time = scenicOrder.getGmtCreate();
            ScenicOrderPayQueryInfoDTO payOrderDTO = new ScenicOrderPayQueryInfoDTO();
            payOrderDTO.setOrderAmount(orderAmount);
            payOrderDTO.setPayDueTime(scenicOrder.getPayExpireDate());
            return Result.success(payOrderDTO);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.failed(new BusinessException(SystemError.SYS_500));
    }

    /**
     * 预订中心下单
     *
     * @param reqList 预订中心订单入参
     * @return 返回值
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result payOrder(List<ScenicPayOrderCollectionReq> reqList, Long userId) {

        if (CollectionUtils.isEmpty(reqList)) {
            throw new BusinessException(SystemError.SYS_416);
        }
        // 每个收款明细对象的  总应收与订单id 相同
        ScenicPayOrderCollectionReq collectionReq = reqList.get(0);
        // 总应收
        BigDecimal countAmount = BigDecimal.ZERO;
        for (ScenicPayOrderCollectionReq orderCollectionReq : reqList) {
            // 币种id
            Long id = orderCollectionReq.getCurrencyId();
            MainDataCurrencyUpdateStatusReq currencyUpdateStatusReq = new MainDataCurrencyUpdateStatusReq();
            currencyUpdateStatusReq.setId(id);
            Result<MainDataCurrencyQueryDTO> queryDTOResult = iMainDataCurrencyService.query(currencyUpdateStatusReq);
            MainDataCurrencyQueryDTO result = queryDTOResult.getData();
            if (null != result) {
                // 汇率
                BigDecimal crmExchangeRate = result.getCrmExchangeRate();
                if (Objects.isNull(crmExchangeRate) || BigDecimal.ZERO.equals(crmExchangeRate)) {
                    throw new BusinessException(SystemError.AIREXPRESS_ORDER_60019);
                }
                BigDecimal collectionAmount = orderCollectionReq.getCollectionAmount();
                // 单个总应收
                BigDecimal multiply = crmExchangeRate.multiply(collectionAmount);
                countAmount = countAmount.add(multiply);
            }
        }
        // 订单id
        Long orderId = collectionReq.getOrderId();

        BigDecimal money = BigDecimal.ZERO;

        for (ScenicPayOrderCollectionReq orderCollectionReq : reqList) {
            // 收款币种id
            Long currencyId = orderCollectionReq.getCurrencyId();
            // 收款金额
            BigDecimal collectionAmount = orderCollectionReq.getCollectionAmount();

            MainDataCurrencyUpdateStatusReq currencyUpdateStatusReq = new MainDataCurrencyUpdateStatusReq();
            currencyUpdateStatusReq.setId(currencyId);
            Result<MainDataCurrencyQueryDTO> queryDTOResult = iMainDataCurrencyService.query(currencyUpdateStatusReq);
            MainDataCurrencyQueryDTO result = queryDTOResult.getData();
            if (null != result) {
                // 汇率
                BigDecimal crmExchangeRate = result.getCrmExchangeRate();
                // 收款金额换算汇率后金额
                BigDecimal multiply = collectionAmount.multiply(crmExchangeRate);
                money = money.add(multiply);
            }
        }
        // 总应收与输入总金额应一致
        if (countAmount.setScale(0, BigDecimal.ROUND_HALF_UP).compareTo(money.setScale(0, BigDecimal.ROUND_HALF_UP)) != 0) {
            throw new BusinessException(SystemError.SCENIC_5001);
        }

        ScenicOrderCollection scenicOrderCollection;
        for (ScenicPayOrderCollectionReq orderCollectionReq : reqList) {
            scenicOrderCollection = EntityUtil.copy(orderCollectionReq, ScenicOrderCollection.class);
            scenicOrderCollection.setId(SnowflakeIdWorker.nextId());
            scenicOrderCollection.setOrderId(orderId);
            scenicOrderCollection.setCreateId(userId);
            String collectionCertificate = orderCollectionReq.getCollectionCertificateJson();
            if (StringUtils.isNotEmpty(collectionCertificate)) {
                String collectionCertificateJson = JSON.toJSONString(collectionCertificate);
                scenicOrderCollection.setCollectionCertificateJson(collectionCertificateJson);
            }
            scenicOrderCollectionMapper.insert(scenicOrderCollection);
        }
        ScenicOrder scenicOrder = scenicOrderMapper.selectById(orderId);
        if(scenicOrder != null){
            scenicOrder.setPaymentStatus(2);
            ScenicProductDetailReq detailReq = new ScenicProductDetailReq();
            detailReq.setId(scenicOrder.getProductId());
            Result<ScenicProductDetailByIdDTO> dtoResult = iScenicProductService.scenicProductDetailByIdDTO(detailReq);
            if(dtoResult.isSuccess() && dtoResult.getData()!= null){
                ScenicProductDetailByIdDTO dto = dtoResult.getData();
                if(dto.getBookConfirm() != null){
                    //预订确认: 1 立即确认  2 二次确认
                    if(dto.getBookConfirm().intValue() == 1){
                        //确认成功
                        scenicOrder.setScheduledStatus(5);
                    }
                    if(dto.getBookConfirm().intValue() == 2){
                        //待确认
                        scenicOrder.setScheduledStatus(4);
                    }
                }
            }
            scenicOrderMapper.updateById(scenicOrder);
        }
        return Result.success();
    }

    /**
     * 订单中心 - 景点门票列表
     *
     * @param scenicOrderReq
     * @return ScenicOrderDTO
     */
    @Override
    public PageResponse<ScenicOrderDTO> list(ScenicOrderReq scenicOrderReq, TokenUser tokenUser) {
       /* Result<List<Long>> permissionResult = sysPermissionService.queryPermission(scenicOrderReq.getMenuId(), tokenUser.getId());
        if (!permissionResult.isSuccess()) {
            SystemError result = SystemError.getDefined(permissionResult.getCode());
            throw new BusinessException(result);
        }*/
        log.info("【查询开始】");
        IPage<ScenicOrder> scenicOrderIPage = null;
        QueryWrapper<ScenicOrder> queryWrapper = new QueryWrapper<>();
        //queryWrapper.lambda().in(!GlobalConstants.Role.isAdmin(tokenUser.getUsername()),ScenicOrder::getCreateId,permissionResult.getData());
        if (StringUtils.isNotBlank(scenicOrderReq.getOrderNumber())) {
            queryWrapper.eq("order_number", scenicOrderReq.getOrderNumber());
        }
        if (StringUtils.isNotBlank(scenicOrderReq.getProductType())) {
            queryWrapper.eq("product_type", scenicOrderReq.getProductType());
        }
        if (StringUtils.isNotBlank(scenicOrderReq.getScheduledStatus())) {
            queryWrapper.eq("scheduled_status", scenicOrderReq.getScheduledStatus());
        }
        if (StringUtils.isNotBlank(scenicOrderReq.getPaymentStatus())) {
            queryWrapper.eq("payment_status", scenicOrderReq.getPaymentStatus());
        }
        //创建开始时间
        if (StringUtils.isNotBlank(scenicOrderReq.getGmtCreateBegin())) {
            queryWrapper.ge("gmt_create", scenicOrderReq.getGmtCreateBegin() + " 00:00:00");
        }
        //创建结束时间
        if (StringUtils.isNotBlank(scenicOrderReq.getGmtCreateEnd())) {
            queryWrapper.le("gmt_create", scenicOrderReq.getGmtCreateEnd() + " 23:23:59");
        }
        queryWrapper.orderByDesc("gmt_create");

        //城市
        log.info("【查询城市列表开始判断城市列表】");
        if (StringUtils.isNotBlank(scenicOrderReq.getCityId())) {
            ScenicProductReq scenicProductReq = new ScenicProductReq();
            scenicProductReq.setScenicId(scenicOrderReq.getCityId());
            log.info("【查询城市列表开始】");
            Result<List<ScenicProductListDTO>> data = iScenicProductService.scenicProductList(scenicProductReq);
            log.info("【查询城市列表结束】");
            List<ScenicProductListDTO> scenicProductListDTOS = data.getData();
            if (CollectionUtils.isNotEmpty(scenicProductListDTOS)) {
                List<Long> ids = new ArrayList<>();
                for (ScenicProductListDTO scenicProductListDTO : scenicProductListDTOS) {
                    ids.add(scenicProductListDTO.getId());
                }
                queryWrapper.in("product_id", ids);
            }
        }
        //景点
        log.info("【查询景点列表开始判断景点列表】");
        if (StringUtils.isNotBlank(scenicOrderReq.getScenicId())) {
            ScenicProductReq scenicProductReq = new ScenicProductReq();
            scenicProductReq.setScenicId(scenicOrderReq.getScenicId());
            log.info("【查询景点列表开始】");
            Result<List<ScenicProductListDTO>> data = iScenicProductService.scenicProductList(scenicProductReq);
            log.info("【查询景点列表结束】");
            List<ScenicProductListDTO> scenicProductListDTOS = data.getData();
            if (CollectionUtils.isNotEmpty(scenicProductListDTOS)) {
                List<Long> ids = new ArrayList<>();
                for (ScenicProductListDTO scenicProductListDTO : scenicProductListDTOS) {
                    ids.add(scenicProductListDTO.getId());
                }
                queryWrapper.in("product_id", ids);
            }
        }
        //联络人
        if (StringUtils.isNotBlank(scenicOrderReq.getContactName())) {
            queryWrapper.like("contact_name", scenicOrderReq.getContactName());
        }
        //订单来源
        if (scenicOrderReq.getSource() != null) {
            queryWrapper.like("source", scenicOrderReq.getSource());
        }
        //销售人员
        if (StringUtils.isNotBlank(scenicOrderReq.getScenicId())) {
            queryWrapper.like("saler_id", scenicOrderReq.getScenicId());
        }
        //内部票号
        log.info("【查询内部票号列表开始判断内部票号列表】");
        if (StringUtils.isNotBlank(scenicOrderReq.getStockNumber())) {
            ScenicProductTicketDetailReq scenicProductTicketDetailReq = new ScenicProductTicketDetailReq();
            scenicProductTicketDetailReq.setStockNumber(scenicOrderReq.getStockNumber());
            log.info("【查询内部票号列表开始】");
            Result<ScenicProductTicketDetailDTO> result = iScenicProductService.scenicProductTicketDetail(scenicProductTicketDetailReq);
            log.info("【查询内部票号列表结束】");
            if (result.isSuccess()) {
                ScenicProductTicketDetailDTO scenicProductTicketDetailDTO = result.getData();
                String productId = scenicProductTicketDetailDTO.getProductId();
                queryWrapper.eq("product_id", productId);
            }
        }
        //供应商票号
        log.info("【查询供应商列表开始判断供应商列表】");
        if (StringUtils.isNotBlank(scenicOrderReq.getSupplierTicketNumber())) {
            ScenicProductTicketDetailReq scenicProductTicketDetailReq = new ScenicProductTicketDetailReq();
            scenicProductTicketDetailReq.setSupplierTicketNumber(scenicOrderReq.getSupplierTicketNumber());
            log.info("【查询供应商列表开始】");
            Result<ScenicProductTicketDetailDTO> result = iScenicProductService.scenicProductTicketDetail(scenicProductTicketDetailReq);
            log.info("【查询供应商列表结束】");
            if (result.isSuccess()) {
                ScenicProductTicketDetailDTO scenicProductTicketDetailDTO = result.getData();
                String productId = scenicProductTicketDetailDTO.getProductId();
                queryWrapper.eq("product_id", productId);
            }
        }
        queryWrapper.and(e -> e.eq("create_id" ,tokenUser.getId()).or().eq("salesman_id" , tokenUser.getId()));
        IPage<ScenicOrder> iPage = new Page<>(scenicOrderReq.getPageNo(), scenicOrderReq.getPageSize());
        log.info("【查询景点订单分页开始】");
        scenicOrderIPage = scenicOrderMapper.selectPage(iPage, queryWrapper);
        log.info("【查询景点订单分页结束】");
        if (CollectionUtils.isEmpty(scenicOrderIPage.getRecords())) {
            log.info("【跳出查询】");
            return PageResponse.empty(scenicOrderIPage.getCurrent());
        }
        List<ScenicOrderDTO> scenicOrderDTOS = new ArrayList<>();
        log.info("【查询产品列表开始】");
        if(!CollectionUtil.isEmpty(scenicOrderIPage.getRecords())){
            List<Long> productids=scenicOrderIPage.getRecords().stream().map(ScenicOrder::getProductId).collect(Collectors.toList());
            Result<List<ScenicProductListDTO>> queryList = iScenicProductService.queryList(StringUtils.join(productids, ","));
            Map<Long,ScenicProductListDTO> productmap=new HashMap<>();
            for(ScenicProductListDTO e:queryList.getData()){
                productmap.put(e.getId(),e);
            }
            log.info("【查询产品列表结束】");
            log.info("【查询景點列表開始】");
            List<Long>  sceneids=queryList.getData().stream().map(ScenicProductListDTO::getScenicId).collect(Collectors.toList());
            Result<List<ScenicDTO>> listResult = sceneService.quertByids(StringUtils.join(sceneids, ","));
            Map<Long,String> scenicmap=new HashMap<>();
            for(ScenicDTO e:listResult.getData()){
                scenicmap.put(e.getId(),e.getName());
            }
            log.info("【查询景點列表结束】");
            scenicOrderIPage.getRecords().forEach(scenicOrder -> {
                ScenicOrderDTO scenicOrderDTO = EntityUtil.copy(scenicOrder, ScenicOrderDTO.class);
                scenicOrderDTO.setProductName(productmap.get(scenicOrder.getProductId()).getName());
                scenicOrderDTO.setCityName(productmap.get(scenicOrder.getProductId()).getCityName());
                scenicOrderDTO.setScenicName(scenicmap.get(productmap.get(scenicOrder.getProductId()).getScenicId()));
                scenicOrderDTOS.add(scenicOrderDTO);
            });
        }
        log.info("【最后一步】");
        PageResponse<ScenicOrderDTO> result =
                new PageResponse<>(scenicOrderDTOS,
                        scenicOrderIPage.getCurrent() == 1,
                        scenicOrderIPage.getTotal() <= (scenicOrderIPage.getCurrent() * scenicOrderIPage.getSize()),
                        scenicOrderIPage.getTotal(), scenicOrderIPage.getCurrent(),
                        scenicOrderIPage.getSize());
        return result;
    }

    /**
     * 构建订单状态
     *
     * @param scenicOrderDetailDTO
     */
    private void buildOrderStatus(ScenicOrderDetailDTO scenicOrderDetailDTO) {
        if (OrderPaymentStatus.UN_PAYMENT.getCode().equals(scenicOrderDetailDTO.getPaymentStatus())) {
            if (scenicOrderDetailDTO.getScheduledStatus() == null) {
                scenicOrderDetailDTO.setOrderStatus(OrderStatus.UN_PAYMENT.getCode());//待付款
            }
        } else if (Objects.equals(OrderPaymentStatus.ALREADY_PAYMENT.getCode(), scenicOrderDetailDTO.getPaymentStatus())) {
            if (Objects.equals(scenicOrderDetailDTO.getScheduledStatus(), ScenicOrderScheduledStatus.CONFIRM_RESERVE.getCode())) {
                scenicOrderDetailDTO.setOrderStatus(OrderStatus.CONFIRM_RESERVE.getCode());//待预订
            } else if (Objects.equals(ScenicOrderScheduledStatus.RESERVE_SUCCESS.getCode(), scenicOrderDetailDTO.getScheduledStatus())) {
                scenicOrderDetailDTO.setOrderStatus(OrderStatus.RESERVE_SUCCESS.getCode());//确认成功
            } else {
                scenicOrderDetailDTO.setOrderStatus(OrderStatus.RESERVE_FAIL.getCode());//确认失败
            }
        } else if (OrderPaymentStatus.ALREADY_CANCEL.getCode().equals(scenicOrderDetailDTO.getPaymentStatus())) {
            scenicOrderDetailDTO.setOrderStatus(OrderStatus.ALREADY_CANCEL.getCode());//已取消
        } else {
            scenicOrderDetailDTO.setOrderStatus(OrderStatus.RESERVE_FAIL.getCode());//确认失败
        }
    }

    @Override
    public Result<ScenicOrderDetailDTO> scenicOrderDetail(ScenicOrderDetailReq scenicOrderDetailReq) {
        ScenicOrder scenicOrder = scenicOrderMapper.selectById(scenicOrderDetailReq.getOrderId());
        ScenicOrderDetailDTO scenicOrderDetailDTO = EntityUtil.copy(scenicOrder, ScenicOrderDetailDTO.class);
        if(scenicOrder != null){
            QueryWrapper<ScenicManualOrder> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("order_id",scenicOrder.getId());
            ScenicManualOrder scenicManualOrder = scenicManualOrderMapper.selectOne(queryWrapper);
            if(scenicManualOrder != null){
                scenicOrderDetailDTO.setTicketMode(scenicManualOrder.getTicketMode());
            }
        }
        buildOrderStatus(scenicOrderDetailDTO);
        ScenicProductDetailReq scenicProductDetailReq = new ScenicProductDetailReq();
        scenicProductDetailReq.setId(scenicOrder.getProductId());
        Result<ScenicProductDetailByIdDTO> scenicProductDetailByIdDTOResult = iScenicProductService.scenicProductDetailByIdDTO(scenicProductDetailReq);
        if (scenicProductDetailByIdDTOResult.isSuccess()) {
            ScenicProductDetailByIdDTO scenicProductDetailByIdDTO = scenicProductDetailByIdDTOResult.getData();
            scenicOrderDetailDTO.setCustomerNotice(scenicProductDetailByIdDTO.getCustomerNotice());
            scenicOrderDetailDTO.setScenicName(scenicProductDetailByIdDTO.getName());
            scenicOrderDetailDTO.setTicketType(scenicProductDetailByIdDTO.getTicketType());
            scenicOrderDetailDTO.setCityName(scenicProductDetailByIdDTO.getCityName());
        }
        String productTicketsIds = scenicOrder.getProductTicketsId();
        String productTicketsId = null;
        if (productTicketsIds != null) {
            if (productTicketsIds.contains(",")) {
                productTicketsId = productTicketsIds.substring(0, productTicketsIds.indexOf(","));
            } else {
                productTicketsId = productTicketsIds;
            }
        }
        if (productTicketsId != null) {
            ScenicProductTicketDetailReq scenicProductTicketDetailReq = new ScenicProductTicketDetailReq();
            scenicProductTicketDetailReq.setId(productTicketsId);
            Result<List<ScenicProductCostStrategySpecAttrDTO>> result = scenicProductCostStrategySpecAttrService.specAttrName(scenicProductTicketDetailReq);
            if (result.isSuccess()) {
                if(result.getData().size() > 0){
                    scenicOrderDetailDTO.setScenicProductCostStrategySpecAttrDTOS(EntityUtil.copyList(result.getData(), com.ctshk.rpc.order.scenic.dto.ScenicProductCostStrategySpecAttrDTO.class));
                }
            }
        }
        if (scenicOrderDetailDTO.getRefundedAmount() != null) {
            scenicOrderDetailDTO.setRealityAmount(scenicOrderDetailDTO.getReceivableAmount().subtract(scenicOrderDetailDTO.getRefundedAmount()));
        } else {
            scenicOrderDetailDTO.setRealityAmount(scenicOrderDetailDTO.getReceivableAmount());
        }
        return Result.success(scenicOrderDetailDTO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result scenicOrderCollection(Scenic0rderCollectionDetailReq scenic0rderCollectionDetailReq, TokenUser user) {
        List<Scenic0rderCollectionListReq> scenic0rderCollectionListReqList = scenic0rderCollectionDetailReq.getScenic0rderCollectionListReqList();
        List<BillAddCollectionReq> req = new ArrayList<>();
        UserDTO userDTO = sysUserService.loadUserByParam(user.getId(), 1);
        if (CollectionUtils.isNotEmpty(scenic0rderCollectionListReqList)) {
            for (Scenic0rderCollectionListReq scenic0rderCollectionListReq : scenic0rderCollectionListReqList) {
                CollectionAmountReq collectionAmountReq = scenic0rderCollectionListReq.getCollectionAmountReq();
                ScenicOrderCollection scenicOrderCollection = new ScenicOrderCollection();
                //生成收款单号,SKD+年後2位+月日4位+時分秒6位+2位隨機數字
                String collectionNumber = "SKD" + DateUtil.fmt(LocalDateTime.now(),"yyMMddHHmmss") + RandomUtil.randomNumbers(2);
                scenicOrderCollection = EntityUtil.copy(scenic0rderCollectionListReq, ScenicOrderCollection.class);
                Scenic0rderCollectionWayReq scenic0rderCollectionWayReq = scenic0rderCollectionListReq.getScenic0rderCollectionWayReq();
                scenicOrderCollection.setCollectionWayId(scenic0rderCollectionWayReq.getValue());
                scenicOrderCollection.setCollectionWay(scenic0rderCollectionWayReq.getLabel());
                scenicOrderCollection.setCollectionNumber(collectionNumber);
                scenicOrderCollection.setCreateId(user.getId());
                scenicOrderCollection.setStatus(0);
                scenicOrderCollection.setOrderId(Long.parseLong(scenic0rderCollectionDetailReq.getOrderId()));
                scenicOrderCollection.setCreateId(collectionAmountReq.getCurrencyId());
                scenicOrderCollection.setCollectionAmount(collectionAmountReq.getHkAmount());
                scenicOrderCollection.setGmtCreate(LocalDateTime.now());
                scenicOrderCollection.setSalerId(user.getId());
                scenicOrderCollection.setSalerName(user.getUsername());
                scenicOrderCollection.setId(SnowflakeIdWorker.nextId());
                BillAddCollectionReq addCollectionReq = new BillAddCollectionReq();
                //收款单号
                addCollectionReq.setBillNumber(collectionNumber);
                addCollectionReq.setBusinessType(SystemBusinessType.ATTRACTION_TICKET.getCode());
                addCollectionReq.setCollectionAmount(collectionAmountReq.getHkAmount());
                addCollectionReq.setCurrencyId(collectionAmountReq.getCurrencyId());
                addCollectionReq.setCurrencyName("HKD"); //收款方式写死
                addCollectionReq.setCollectionTypeName("全款");
                //addCollectionReq.setCurrencyName(collectionAmountReq.getCurrencyCode());


                addCollectionReq.setCollectionWayId(scenic0rderCollectionWayReq.getValue());
                addCollectionReq.setCollectionWayName(scenic0rderCollectionWayReq.getLabel());
                MainDataCurrencyUpdateStatusReq dataCurrencyUpdateStatusReq = new MainDataCurrencyUpdateStatusReq();
                dataCurrencyUpdateStatusReq.setId(collectionAmountReq.getCurrencyId());
                Result<MainDataCurrencyQueryDTO> query = iMainDataCurrencyService.query(dataCurrencyUpdateStatusReq);
                addCollectionReq.setExchangeRate(query.getData().getMarketExchangeRate().doubleValue());
                addCollectionReq.setCollectionTime(LocalDateTime.now());
                addCollectionReq.setSaleOrderId(Long.parseLong(scenic0rderCollectionDetailReq.getOrderId()));
                addCollectionReq.setSaleUserId(user.getId());
                addCollectionReq.setSaleUserName(userDTO.getCnName());
                SysDepartmentDTO departmentDTO = sysDepartmentService.queryOne(userDTO.getDeptId());
                addCollectionReq.setSaleDeptId(departmentDTO.getId());
                addCollectionReq.setUserId(user.getId());

                ScenicOrder scenicOrder = scenicOrderMapper.selectById(scenic0rderCollectionDetailReq.getOrderId());
                if (scenicOrder != null) {
                    addCollectionReq.setSaleOrderNumber(scenicOrder.getOrderNumber());
                    scenicOrder.setPaymentStatus(2);
                    scenicOrder.setGmtModified(LocalDateTime.now());
                    scenicOrder.setModifiedId(user.getId());
                    ScenicProductDetailReq detailReq = new ScenicProductDetailReq();
                    detailReq.setId(scenicOrder.getProductId());
                    Result<ScenicProductDetailByIdDTO> dtoResult = iScenicProductService.scenicProductDetailByIdDTO(detailReq);
                    if(dtoResult.isSuccess() && dtoResult.getData()!= null){
                        ScenicProductDetailByIdDTO dto = dtoResult.getData();
                        if(dto.getBookConfirm() != null){
                            //预订确认: 1 立即确认  2 二次确认
                            if(dto.getBookConfirm() == 1){
                                //确认成功
                                scenicOrder.setScheduledStatus(5);
                            }
                            if(dto.getBookConfirm().intValue() == 2){
                                //待确认
                                scenicOrder.setScheduledStatus(4);
                            }
                        }
                    }
                    scenicOrderMapper.updateById(scenicOrder);
                    Result<ScenicProductListDTO> result = scenicProductService.queryById(scenicOrder.getProductId());
                    if (result.isSuccess()) {
                        ScenicProductListDTO scenicProductListDTO = result.getData();
                        addCollectionReq.setProductName(scenicProductListDTO.getName());
                        addCollectionReq.setProductNumber(scenicProductListDTO.getProductCode());
                        List<Long> productId = new ArrayList<>();
                        productId.add(scenicProductListDTO.getId());
                        addCollectionReq.setProductId(productId);
                        List<String> resourceInfo = new ArrayList<>();
                        resourceInfo.add(scenicProductListDTO.getName());
                        addCollectionReq.setResourceInfo(resourceInfo);
                        req.add(addCollectionReq);
                    }
                }
                scenicOrderCollectionMapper.insert(scenicOrderCollection);
            }
            financeBillService.addCollection(req);
        }
        return Result.success();
    }

    @Override
    public Result<Long> cancelScenicOrder(Scenic0rderCancelReq scenic0rderCancelReq, TokenUser tokenUser) {

        ScenicOrder scenicOrder = scenicOrderMapper.selectById(scenic0rderCancelReq.getOrderId());
        switch (scenicOrder.getPaymentStatus()) {
            case 1:
                scenicOrder.setPaymentStatus(3);
                scenicOrder.setRefundReason(scenic0rderCancelReq.getCancelReason());
                scenicOrder.setRemark(scenic0rderCancelReq.getRemark());
                scenicOrder.setGmtModified(LocalDateTime.now());
                scenicOrder.setModifiedId(tokenUser.getId());
                scenicOrderMapper.updateById(scenicOrder);
                break;
        }
        return Result.success(Long.parseLong(scenic0rderCancelReq.getOrderId()));
    }

    @Transactional
    @Override
    public Result<Long> cancelScenicOrderRefund(Scenic0rderRefundDetailReq scenic0rderCancelReq, TokenUser tokenUser) {
        ScenicOrder scenicOrder = scenicOrderMapper.selectById(scenic0rderCancelReq.getOrderId());
        scenicOrder.setCancelStatus(ApprovalStatus.REVIEWING.getCode());
        scenicOrder.setRefundReason(scenic0rderCancelReq.getCancelReason());
        scenicOrder.setRemark(scenic0rderCancelReq.getRemark());
        scenicOrder.setGmtModified(LocalDateTime.now());
        scenicOrder.setModifiedId(tokenUser.getId());
        scenicOrderMapper.updateById(scenicOrder);
        List<ScenicOrderRefund> list = new ArrayList<>();
        List<Scenic0rderRefundListReq> scenic0rderRefundListReqList = scenic0rderCancelReq.getScenic0rderRefundListReqList();
        if (CollectionUtils.isNotEmpty(scenic0rderRefundListReqList)) {
            for (Scenic0rderRefundListReq visa0rderRefundListReq : scenic0rderRefundListReqList) {
                ScenicOrderRefund scenicOrderRefund = new ScenicOrderRefund();
                scenicOrderRefund = EntityUtil.copy(visa0rderRefundListReq, ScenicOrderRefund.class);
                Scenic0rderRefundWayReq scenic0rderRefundWayReq = visa0rderRefundListReq.getScenic0rderRefundWayReq();
                if(scenic0rderRefundWayReq != null){
                    scenicOrderRefund.setRefundWayId(Long.parseLong(scenic0rderRefundWayReq.getValue()));
                    scenicOrderRefund.setRefundWay(scenic0rderRefundWayReq.getLabel());
                }
                scenicOrderRefund.setId(SnowflakeIdWorker.nextId());
                RefundAmountReq refundAmountReq = visa0rderRefundListReq.getRefundAmountReq();
                if(refundAmountReq != null){
                    BigDecimal crmExchangeRate = getCrmExchangeRateByName(refundAmountReq.getCurrencyName());
                    BigDecimal refundAmount = refundAmountReq.getCollectionAmount().multiply(crmExchangeRate);
                    scenicOrderRefund.setRefundAmount(refundAmount);
                    scenicOrderRefund.setExchangeRate(crmExchangeRate);
                    scenicOrderRefund.setCurrency(refundAmountReq.getCurrencyName());
                }
                scenicOrderRefund.setOrderId(Long.parseLong(scenic0rderCancelReq.getOrderId()));
                scenicOrderRefund.setRefundNumber(NumberUtil.generateOrderHotelRefundNumber(LocalDateTime.now()));
                scenicOrderRefund.setRefundReason(scenic0rderCancelReq.getCancelReason());
                scenicOrderRefund.setStatus(ApprovalStatus.REVIEWING.getCode());
                scenicOrderRefund.setRejectReason(scenic0rderCancelReq.getRemark());
                scenicOrderRefund.setModifiedId(tokenUser.getId());
                scenicOrderRefund.setGmtCreate(LocalDateTime.now());
                scenicOrderRefund.setCreateId(tokenUser.getId());
                scenicOrderRefundMapper.insert(scenicOrderRefund);
                list.add(scenicOrderRefund);
            }

        }
        Result<ApprovalStartDTO> result =
                iSysApprovalService.start(SystemBusinessType.ATTRACTION_TICKET.getCode(),
                        SysApprovalType.CANCEL_TICKET.getCode(),
                        Long.parseLong(scenic0rderCancelReq.getOrderId()),
                        tokenUser.getId(), null, JSON.toJSONString(list));

        return Result.success(Long.parseLong(scenic0rderCancelReq.getOrderId()));
    }

    @Override
    public Result<Long> cancelApproval(ScenicOrderCheckReq scenicOrderCheckReq, TokenUser tokenUser) {
        if (scenicOrderCheckReq.getId() == null) {
            return Result.failed(SystemError.SYS_402);
        }
        if (!ApprovalStatus.isCheckStatus(scenicOrderCheckReq.getStatus())) {
            return Result.failed(SystemError.SYS_402);
        }
        QueryWrapper<ScenicOrder> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.lambda().eq(ScenicOrder::getId, scenicOrderCheckReq.getOrderId());
        orderQueryWrapper.lambda().eq(ScenicOrder::getIsDeleted, IsDeletedCode.NO);
        ScenicOrder scenicOrder = scenicOrderMapper.selectOne(orderQueryWrapper);
        if (scenicOrder == null) {
            return Result.failed(SystemError.AIREXPRESS_ORDER_60002);
        }
        if (!ApprovalStatus.REVIEWING.getCode().equals(scenicOrder.getCancelStatus())) {
            return Result.failed(SystemError.AIREXPRESS_ORDER_60027);
        }
        QueryWrapper<ScenicOrderRefund> orderRefundQueryWrapper = new QueryWrapper<>();
        orderRefundQueryWrapper.lambda().eq(ScenicOrderRefund::getOrderId, scenicOrderCheckReq.getOrderId());
        orderRefundQueryWrapper.lambda().eq(ScenicOrderRefund::getIsDeleted, IsDeletedCode.NO);
        List<ScenicOrderRefund> scenicOrderRefundList = scenicOrderRefundMapper.selectList(orderRefundQueryWrapper);
        if (CollectionUtils.isEmpty(scenicOrderRefundList)) {
            return Result.failed(SystemError.AIREXPRESS_ORDER_60028);
        }
        LocalDateTime nowLocalDateTime = LocalDateTime.now();
        log.info("【景点门票-退款】approval status:{}", scenicOrderCheckReq.getStatus());
        if (ApprovalStatus.REVIEW_YES.getCode() == scenicOrderCheckReq.getStatus()) {
            if (CollectionUtils.isEmpty(scenicOrderCheckReq.getScenicOrderRefundApprovalRecordReqList())) {
                throw new BusinessException(SystemError.AIREXPRESS_ORDER_60036);
            }
            // 审批通过
            scenicOrder.setCancelStatus(ApprovalStatus.REVIEW_YES.getCode());
            scenicOrder.setScheduledStatus(OrderScheduledStatus.RESERVE_FAIL.getCode()); //取消
            // 校验审批金额
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (ScenicOrderRefund refund : scenicOrderRefundList) {
                refund.setStatus(ApprovalStatus.REVIEW_YES.getCode());
                for (ScenicOrderRefundApprovalRecordReq scenicOrderRefundApprovalRecordReq : scenicOrderCheckReq.getScenicOrderRefundApprovalRecordReqList()) {
                    if (Objects.equals(scenicOrderRefundApprovalRecordReq.getId(), refund.getId())) {
                        BigDecimal approvalAmount = scenicOrderRefundApprovalRecordReq.getApprovalAmount();
                        totalAmount = totalAmount.add(approvalAmount.multiply(refund.getExchangeRate()));
                        refund.setApprovalAmount(scenicOrderRefundApprovalRecordReq.getApprovalAmount());
                        break;
                    }
                }
            }
            //需要修改
            /*BigDecimal cancellationCharge = airportExpressService.getCancellationChargeById(airportExpressOrder.getAirportExpressId(), airportExpressOrder.getReceivableAmount());
            BigDecimal refundAmount = airportExpressOrder.getReceivableAmount().subtract(cancellationCharge);
            if (totalAmount.compareTo(refundAmount) > 0) {
                throw new BusinessException(SystemError.AIREXPRESS_ORDER_60035);
            }*/
            /**
             * 新增财务退款记录
             */
            log.info("【景点门票订单】生成供应商预订，查询景点门票信息, id:{}", scenicOrder.getProductId());
            ScenicProductDetailReq req = new ScenicProductDetailReq();
            req.setId(scenicOrder.getProductId());
            Result<ScenicProductDetailByIdDTO> dtoResult = scenicProductService.scenicProductDetailByIdDTO(req);
            ScenicProductDetailByIdDTO dto = new ScenicProductDetailByIdDTO();
            if (dtoResult.isSuccess() && dtoResult.getData() != null) {
                dto = dtoResult.getData();
            }
           /* log.info("【机场快线订单】生成供应商预订，查询机场快线信息, info:{}", JSON.toJSONString(airportExpressInfoDTO));
            UserDTO userSaleDTO = sysUserService.queryCacheUser(airportExpressOrder.getSalesmanId());*/
            UserDTO userDTO = iSysUserService.loadUserByParam(tokenUser.getId(), 1);
            List<BillAddRefundReq> billAddRefundReqs = new ArrayList<>();
            for (ScenicOrderRefund orderRefund : scenicOrderRefundList) {
                BillAddRefundReq billAddRefundReq = new BillAddRefundReq();
                billAddRefundReqs.add(billAddRefundReq);
                billAddRefundReq.setBillNumber(orderRefund.getRefundNumber());
                billAddRefundReq.setBusinessType(SystemBusinessType.AIR_EXPRESS.getCode());
                billAddRefundReq.setCollectionAmount(orderRefund.getRefundAmount());
                billAddRefundReq.setCurrencyId(orderRefund.getCurrencyId());
                billAddRefundReq.setCurrencyName(orderRefund.getCurrency());
                billAddRefundReq.setExchangeRate(orderRefund.getExchangeRate().doubleValue());
                billAddRefundReq.setRefundTime(orderRefund.getGmtCreate());
                billAddRefundReq.setSaleOrderNumber(scenicOrder.getOrderNumber());
                billAddRefundReq.setSaleOrderId(scenicOrder.getId());
                billAddRefundReq.setProductId(Arrays.asList(scenicOrder.getProductId()));
                billAddRefundReq.setProductName(dto.getName());
                billAddRefundReq.setProductNumber(dto.getProductCode());
                billAddRefundReq.setResourceInfo(Arrays.asList(dto.getName()));
                billAddRefundReq.setSaleUserId(tokenUser.getId());
                billAddRefundReq.setSaleUserName(userDTO.getFullName());
                billAddRefundReq.setSaleDeptId(userDTO.getDeptId());
                billAddRefundReq.setUserId(tokenUser.getId());
            }
            log.info("【景点门票订单退款】新增财务退款记录，req:{}", JSON.toJSONString(billAddRefundReqs));
            financeBillService.addRefund(billAddRefundReqs);
            QueryWrapper<ScenicOrderTourist> orderTouristQueryWrapper = new QueryWrapper<>();
            orderTouristQueryWrapper.eq("order_id", scenicOrderCheckReq.getOrderId());
            //执行返回库存  返回票号
            List<ScenicOrderTourist> tourists=scenicOrderTouristMapper.selectList(orderTouristQueryWrapper);
            List<Long> ticketIds=tourists.stream().map(ScenicOrderTourist::getTicketsProductId).collect(Collectors.toList());
            if(!CollectionUtil.isEmpty(ticketIds)){
                iScenicResourceTicketService.backTicket(StringUtils
                        .join(ticketIds,","));
                ScenicResourceTicketReq ticketReq=new ScenicResourceTicketReq();
                ticketReq.setId(ticketIds.get(0).toString());
                Result<ScenicResourceTicketDTO> result= iScenicResourceTicketService.queryDetail(ticketReq);
                scenicProductCostStrategySpecAttrService.updateAddStock(result.getData().getStockId(),ticketIds.size());
            }
        } else if (ApprovalStatus.REVIEW_NO.getCode() == scenicOrderCheckReq.getStatus()) {
            //审批不通过
            scenicOrder.setCancelStatus(ApprovalStatus.REVIEW_NO.getCode());
            for (ScenicOrderRefund scenicOrderRefund : scenicOrderRefundList) {
                scenicOrderRefund.setStatus(ApprovalStatus.REVIEW_NO.getCode());
            }
        } else {
            //撤回
            scenicOrder.setCancelStatus(null);
            for (ScenicOrderRefund scenicOrderRefund : scenicOrderRefundList) {
                scenicOrderRefund.setStatus(null);
                scenicOrderRefund.setIsDeleted(IsDeletedCode.YES.getCode());
            }
        }
        /**
         * 审批
         */
        Result<ApprovalCheckDTO> result = iSysApprovalService.check(scenicOrderCheckReq.getId(), tokenUser.getId(),
                scenicOrderCheckReq.getStatus(), scenicOrderCheckReq.getComments());
        if (!result.isSuccess()) {
            SystemError systemError = SystemError.getDefined(result.getCode());
            return Result.failed(systemError);
        }
        if (result.getData() == null || !result.getData().getIsFinish()) {
            return Result.success(scenicOrderCheckReq.getId());
        }
        for (ScenicOrderRefund scenicOrderRefund : scenicOrderRefundList) {
            scenicOrderRefund.setModifiedId(tokenUser.getId());
            scenicOrderRefund.setGmtModified(nowLocalDateTime);
            scenicOrderRefundMapper.updateById(scenicOrderRefund);
        }
        scenicOrder.setModifiedId(tokenUser.getId());
        scenicOrder.setGmtModified(nowLocalDateTime);
        scenicOrderMapper.updateById(scenicOrder);
        return Result.success(scenicOrderCheckReq.getId());
    }

    @Override
    public Result<Long> confirmOrder(ScenicProductOrderReq scenicProductOrderReq, TokenUser tokenUser) {
        iScenicProductService.modifyProductTicket(EntityUtil.copyList(scenicProductOrderReq.getScenicProductTicketListReqList(), ScenicProductTicketListReq.class), tokenUser);
        ScenicOrder scenicOrder = scenicOrderMapper.selectById(scenicProductOrderReq.getOrderId());
        scenicOrder.setFileJson(scenicProductOrderReq.getFileJson());
        scenicOrderMapper.updateById(scenicOrder);
        return Result.success(scenicOrder.getId());
    }

    @Override
    public Result notice(Scenic0rderNoticeReq scenic0rderNoticeReq) {
        //MailUtil.sendSimpleTextMail("1204920594@qq.com","","333");
        return Result.success();
    }

    @Override
    public Result<Long> approve(ScenicOrderApproveReq scenicOrderApproveReq, TokenUser tokenUser) {
        Result<ApprovalCheckDTO> result = iSysApprovalService.check(scenicOrderApproveReq.getId(), tokenUser.getId(), scenicOrderApproveReq.getStatus(), null);
        if (result.getData().getIsFinish()) {
            ScenicOrder scenicOrder = scenicOrderMapper.selectById(scenicOrderApproveReq.getOrderId());
            scenicOrder.setCancelStatus(scenicOrderApproveReq.getStatus());
            scenicOrder.setGmtModified(LocalDateTime.now());
            scenicOrder.setModifiedId(tokenUser.getId());
            scenicOrderMapper.updateById(scenicOrder);
        } else {
            Result result1 = new Result();
            result1.setCode(result.getCode());
            result1.setMsg(result.getMsg());
            return result1;
        }
        return Result.success(scenicOrderApproveReq.getOrderId());
    }

    @Override
    public Result<List<MyScenicOrderDTO>> recentToNow(LocalDateTime recent, LocalDateTime now) {
        List<ScenicOrder> orderList = baseMapper.selectList(Wrappers.<ScenicOrder>lambdaQuery()
                .eq(ScenicOrder::getIsDeleted,IsDeletedCode.NO.getCode())
                .ge(recent != null,ScenicOrder::getGmtModified, recent)
                .le(ScenicOrder::getGmtModified, now));

        List<MyScenicOrderDTO> result = new ArrayList<>();
        for (ScenicOrder scenicOrder : orderList) {
            MyScenicOrderDTO orderDTO = EntityUtil.copy(scenicOrder, MyScenicOrderDTO.class);
            Result<ScenicProductListDTO> scenicProductListDTOResult = scenicProductService.queryById(orderDTO.getProductId());
            if(scenicProductListDTOResult.isSuccess()) {
                ScenicProductListDTO data = scenicProductListDTOResult.getData();
                orderDTO.setVaildDayBegin(data.getVaildDayBegin());
                orderDTO.setVaildDayEnd(data.getVaildDayEnd());
            }
            result.add(orderDTO);
        }
        return Result.success(result);
    }

    /**
     * 根据币种名称获取汇率
     *
     * @param currencySy
     * @return
     */
    private BigDecimal getCrmExchangeRateByName(String currencySy) {
        MainDataCurrencyListReq mainDataCurrencyListReq = new MainDataCurrencyListReq();
        mainDataCurrencyListReq.setName(currencySy);
        PageResponse<MainDataCurrencyListDTO> list = iMainDataCurrencyService.list(mainDataCurrencyListReq);
        if (CollectionUtils.isEmpty(list.getRecords())) {
            throw new BusinessException(SystemError.AIREXPRESS_ORDER_60003);
        }
        return list.getRecords().get(0).getCrmExchangeRate();
    }

    @Override
    public Result supplierConfirmOrder(ConfirmProductTickeReq confirmReq) {
        switch (confirmReq.getConfirmType()){
            case 1:
                //修改供应商票号
                for(ProductTicketDTO ticke: confirmReq.getProductTicketDTO()){
                    iScenicResourceTicketService.updateSupplierTicketNumberByid(ticke.getProductTickeId(),
                            ticke.getSupplierTicketNumber());
                }
                scenicOrderMapper.updateByOrderNumber(confirmReq.getSaleNumber(),5);
                break;
            case 2:
//                ScenicOrder scenicOrder1 = new ScenicOrder();
//                scenicOrder1.setId(confirmReq.getOrderId());
//                scenicOrder1.set(2);
//                scenicOrderMapper.updateById(scenicOrder);
                break;
        }
        return Result.success();
    }

    @Override
    public Result<Integer> querySalaNumber(Integer type, Long productId, Long Id) {
        switch (type){
            case 1:
                return Result.success(scenicOrderMapper.querySalaNumber(productId,Id));
            case 2:
                return  Result.success(scenicOrderMapper.querySalaNumberByAgent(productId,Id));
        }
        return null;
    }
}
















